﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Coder.Workflow;
using Fee.Orders;
using Fee.Orders.AuthProjectWorkflow;
using Fee.Stores;
using Identity;
using Microsoft.EntityFrameworkCore;
using Ornament.ImportHelper;
using Text.Helper;

namespace Fee.IO.Importers
{
    public class AuthProjectImport<T> : BaseImporter<T> where T : FeeDbContext
    {
        private readonly AuthProjectManager<T> _manager;
        private readonly User _user;
        private readonly IConstructionTaskStore<T> _constructionTaskStore;
        private readonly int? _workActivityId;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="manager"></param>
        /// <param name="user"></param>
        /// <param name="constructionTaskStore"></param>
        /// <param name="workActivityId">是否用来更新工作内容</param>
        /// <param name="createWf">是否创建工作流</param>
        /// <para></para>
        public AuthProjectImport(T context, AuthProjectManager<T> manager, User user,
            IConstructionTaskStore<T> constructionTaskStore, int? workActivityId = null, bool createWf = false) : base(context, createWf)
        {
            _manager = manager;
            _user = user;
            _constructionTaskStore = constructionTaskStore;
            _workActivityId = workActivityId;
        }

        public IEnumerable<StationCostDetail> StationCostDetails()
        {
            foreach (var item in _stations.Values)
            {
                foreach (var costDetail in item.CostDetails)
                {
                    costDetail.CalculateBy(item.ConstructionTask);
                }

            }
            return _stations.Values;
        }

        readonly IDictionary<string, StationCostDetail> _stations = new ConcurrentDictionary<string, StationCostDetail>();
        protected override bool ConverTo(IList<string> rowStringInfo, out ImportResultItem item)
        {
            //站点编码 专业	总投资	建筑安装工程费	材料费
            //乙供材料费	辅助材料费	规费	安全生产费	施工协调费
            //建设/占道协调费	零星材料及资料录入费
            //监理费	设计费	甲供物资费用	设备费	预覆盖数据录入费
            //中间站跳纤设计费	传输资源录入费
            item = new ImportResultItem();

            var index = 0;
            var stationCode = rowStringInfo.ImportString(index++, "站点编码", item);
            var station = Context.Stations.FirstOrDefault(_ => _.Code == stationCode);

            StationCostDetail detail = null;
            if (!_stations.ContainsKey(stationCode))
            {
                detail = new StationCostDetail();

                _stations.Add(stationCode, detail);
            }
            else
            {
                detail = _stations[stationCode];

            }

            if (station == null)
            {
                item.AddError(0, stationCode + "站点不存在");
            }

            if (station != null && station.Status != StationStatus.Complete)
            {
                item.AddError(0, "站点处于 " + station.Status.GetEnumDisplayName() + " 不能创建订单。");
            }

            if (station != null)
            {
                var task = _constructionTaskStore.GetByStation(station.Id);

                if (task == null)
                {
                    item.AddError(0, "站点处于还没完成‘正式委托',创建工地失败.");
                }
                else
                {
                    detail.ConstructionTask = task;
                }
            }

            AuthProjectOrderCostDetail costDetail = new AuthProjectOrderCostDetail();
            detail.CostDetails.Add(costDetail);

            costDetail.Type = rowStringInfo.ImportEnum<ConstructionType>(index++, "专业", item, true);
            costDetail.TotalAmount = rowStringInfo.ImportDecimal(index++, "总投资", item, true);
            costDetail.ConstructionsSetupAmount = rowStringInfo.ImportDecimal(index++, "建筑安装工程费", item, true);
            costDetail.MaterialFee = rowStringInfo.ImportDecimal(index++, "材料费", item, true);

            costDetail.VendorMaterialFee = rowStringInfo.ImportDecimal(index++, "乙供材料费", item, true);
            costDetail.SecondaryMaterial = rowStringInfo.ImportDecimal(index++, "辅助材料费", item, true);
            costDetail.RuleCost = rowStringInfo.ImportDecimal(index++, "规费", item, true);
            costDetail.SafeProduce = rowStringInfo.ImportDecimal(index++, "安全生产费", item, true);
            costDetail.ConstructionCoordination = rowStringInfo.ImportDecimal(index++, "施工协调费", item, true);

            costDetail.ConstructionOccupancy = rowStringInfo.ImportDecimal(index++, "建设/占道协调费", item, true);
            costDetail.SporadicMaterialAndInputInfo = rowStringInfo.ImportDecimal(index++, "零星材料及资料录入费", item, true);

            costDetail.Supervisor = rowStringInfo.ImportDecimal(index++, " 监理费（降点前）", item, true);
            costDetail.Design = rowStringInfo.ImportDecimal(index++, "设计费（降点前）", item, true);
            costDetail.FirstPartyMeterial = rowStringInfo.ImportDecimal(index++, "甲供物资费用", item, true);
            costDetail.Equipment = rowStringInfo.ImportDecimal(index++, "设备费", item, true);
            costDetail.PreConverageDataInput = rowStringInfo.ImportDecimal(index++, "预覆盖数据录入费", item, true);

            costDetail.MiddleStationJumperDesign = rowStringInfo.ImportDecimal(index++, "中间站跳纤设计费", item, true);
            costDetail.TransferDataInput = rowStringInfo.ImportDecimal(index++, "传输资源录入费", item, true);

            return !item.HasError;
        }
        public OrderResult<AuthProjectOrder> OrderResult { get; set; }
        public override void SaveToDb(IList<ImportResultItem> importResult, T t)
        {
            OrderResult<AuthProjectOrder> orderResult;
            if (this._workActivityId == null)
            {

                orderResult = _manager.Create(_user);
            }
            else
            {
                this.CurrentWorkActivity = _manager.GetWorkActivity(_workActivityId.Value, true);
                orderResult = new OrderResult<AuthProjectOrder>();
                orderResult.Successed = true;
                orderResult.Message = "";
                orderResult.Order = _manager.GetById(this.CurrentWorkActivity.ProcessInstance.Id);


            }
            orderResult.Order.CostDetails.Clear();
            foreach (var detail in _stations.Values)
            {
                orderResult.Order.CostDetails.Add(detail);
            }

            this.OrderResult = orderResult;
            if (this._workActivityId == null)
            {
                CurrentWorkActivity = _manager.Start(orderResult.Order).FirstOrDefault();
                CurrentWorkActivity.AssignTo(this._user);
            }

        }

        public WorkActivity CurrentWorkActivity { get; set; }
    }
}